# -*- coding: utf-8 -*-
"""
@Time ： 2022/12/26 21:38
@Auth ： jiraWu
@File ：_request.py
@IDE ：PyCharm
@Motto:人生苦短，我学Python
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
"""

"""
构建一个请求类
"""
__all__ = ['GetRequest', 'PostRequest']

# 请求，转码库
from urllib import request, parse
# 随机数
import random
# 参数类型
from typing import Union


class Request:
    pass


"""
get请求的类
"""


class GetRequest(Request):
    def __init__(self, url: str, headers: dict[str, str] = None, data: dict = None):
        """
        初始化
        :param url: 请求地址
        :param headers: 请求头
        :param data: 请求参数
        """
        if headers is None:
            headers = {}
        if data is None:
            data = {}
        self.url = (url + parse.urlencode(data))  # 拼接url
        self.headers = headers
        self.data = data

    def __str__(self):
        return f"请求地址:{self.url},请求方法:【GET】,请求头:{self.headers},请求数据:{self.data}"

    def send_req(self):
        """
        发起请求
        :return: None
        """
        req = request.Request(url=self.url, headers=self.headers)  # 定制请求
        resp = request.urlopen(req)  # 打开链接
        cont = resp.read().decode("utf-8")  # 读取数据
        return cont

    def proxy_req(self, proxies: Union[dict, list[dict]]):
        """
         代理请求
        :param proxies: 代理ip
        :return:
        """
        req = request.Request(url=self.url, headers=self.headers)  # 请求定制
        """
        判断传过来的代理ip类型
        字典：直接请求
        列表：随机挑1个ip再请求
        """
        if type(proxies) == type({}):
            handler = request.ProxyHandler(proxies=proxies)  # 获取handler对象
            opener = request.build_opener(handler)  # 获取opener对象
            resp = opener.open(req)  # 打开链接
            cont = resp.read().decode('utf-8')  # 获取内容 读出来是字节 所以要解码
            return cont
        elif type(proxies) == type([]):
            if not type(proxies[0]) == type({}):
                print("proxies类型错误,proxies[disc|list[dict]]")
                return
            proxy_val = self.__choose_proxy(proxies)  # 挑取代理ip
            handler = request.ProxyHandler(proxies=proxy_val)  # 获取handler对象
            opener = request.build_opener(handler)  # 获取opener对象
            resp = opener.open(req)  # 打开链接
            cont = resp.read().decode('utf-8')  # 获取内容 读出来是字节 所以要解码
            return cont
        else:
            print("proxies类型错误,disc|list")

    def __choose_proxy(self, proxies):
        """
        在代理池选择1个代理ip
        :return: 代理ip
        """
        proxy_val = random.choice(proxies)
        return proxy_val

    def down_load_file(self, filename: str):
        """
        下载文件
        :param: filename: 路径\文件名
        :return: None
        """
        request.urlretrieve(url=self.url, filename=filename)


"""
post请求类
"""


class PostRequest(Request):
    def __init__(self, url: str, headers: dict[str, str] = None, data: dict = None):
        """
        初始化
        :param url: 请求地址
        :param headers: 请求头
        :param data: 请求参数
        """
        if headers is None:
            headers = {}
        if data is None:
            data = {}
        self.url = url
        self.headers = headers
        self.data = (parse.urlencode(data).encode('utf-8'))  # Unicode编码后序列化

    def send_req(self):
        """
        发送请求
        :return: 请求内容
        """
        req = request.Request(url=self.url, data=self.data, headers=self.headers)
        resp = request.urlopen(req)
        cont = resp.read().decode('utf-8')
        return cont

    def proxy_req(self, proxies: Union[dict, list[dict]]):
        """
         代理请求
        :param proxies: 代理ip
        :return:
        """
        req = request.Request(url=self.url, headers=self.headers, data=self.data)  # 请求定制
        """
        判断传过来的代理ip类型
        字典：直接请求
        列表：随机挑1个ip再请求
        """
        if type(proxies) == type({}):
            handler = request.ProxyHandler(proxies=proxies)  # 获取handler对象
            opener = request.build_opener(handler)  # 获取opener对象
            resp = opener.open(req)  # 打开链接
            cont = resp.read().decode('utf-8')  # 获取内容 读出来是字节 所以要解码
            return cont
        elif type(proxies) == type([]):
            if not type(proxies[0]) == type({}):
                print("proxies类型错误,proxies[disc|list[dict]]")
                return
            proxy_val = self.__choose_proxy(proxies)  # 挑取代理ip
            handler = request.ProxyHandler(proxies=proxy_val)  # 获取handler对象
            opener = request.build_opener(handler)  # 获取opener对象
            resp = opener.open(req)  # 打开链接
            cont = resp.read().decode('utf-8')  # 获取内容 读出来是字节 所以要解码
            return cont
        else:
            print("proxies类型错误,disc|list")

    def __choose_proxy(self, proxies):
        """
        在代理池选择1个代理ip
        :return: 代理ip
        """
        proxy_val = random.choice(proxies)
        return proxy_val

    def __str__(self):
        return f"请求地址:{self.url},请求方法:【POST】,请求头:{self.headers},请求数据:{self.data}"


if __name__ == '__main__':
    print("自定义请求工具")
    """
    下载
    """
    url = "http://www.baidu.com"
    get = GetRequest(url=url).send_req()
    print(get)
